﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlServer.Management.Smo;
using System.Text.RegularExpressions;

namespace GeneratorLibrary.DatabaseCompare {
    public enum ComparisonValue {
        FirstExists, SecondExists, Equal, Different
    }
    public class DataRef {
        string objectType;
        string name;
        string script1;
        string script2;
        ComparisonValue comparisonValue;

        public ComparisonValue ComparisonValue {
            get { return comparisonValue; }
            set { comparisonValue = value; }
        }

        public string ObjectType {
            get { return objectType; }
            set { objectType = value; }
        }

        public string Name {
            get { return name; }
            set { name = value; }
        }

        public string Script1 {
            get { return script1; }
            set { script1 = value; }
        }

        public string Script2 {
            get { return script2; }
            set { script2 = value; }
        }

        public string Key {
            get {
                return ObjectType + "." + Name;
            }
        }

        public DataRef(NamedSmoObject item, string type) {
            ObjectType = type;
            name = item.Name;
        }

        internal string[] DoCompare() {
            if (script1 == null)
                ComparisonValue = ComparisonValue.SecondExists;
            else if (script2 == null)
                ComparisonValue = ComparisonValue.FirstExists;
            else if (areEqual())
                ComparisonValue = ComparisonValue.Equal;
            else
                ComparisonValue = ComparisonValue.Different;

            return ListValue();
        }

        private string[] ListValue() {
            string[]ary = new string[5];
            ary[3] = objectType;
            switch (ComparisonValue) {
                case ComparisonValue.FirstExists:
                    ary[0] = name;
                    ary[1] = "----->";
                    break;
                case ComparisonValue.SecondExists:
                    ary[2] = name;
                    ary[1] = "<-----";
                    break;
                case ComparisonValue.Equal:
                    ary[0] = name;
                    ary[1] = " ===== ";
                    ary[2] = name;
                    break;
                case ComparisonValue.Different:
                    ary[0] = name;
                    ary[1] = "<----- != ----->";
                    ary[2] = name;
                    break;
            }
            return ary;
        }

        private bool areEqual() {
            Regex r = new Regex("\\s+");
            string test1 = r.Replace(script1, " ");
            string test2 = r.Replace(script2, " ");
            if (test1 == test2)
                return true;
            else {
                string[] lines1 = script1.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                string[] lines2 = script2.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                return testLines(lines1, lines2) && testLines(lines2, lines1);
            }
        }
        static Regex reg = new Regex("\\s\\s+");
        private bool testLines(string[] lines, string[] comparison) {
            foreach (string s in lines) {
                string s2 = s.Trim(new char[] { ',', ' ', '\t', '\r', '\n' }).Replace("[", "").Replace("]", "").Replace("dbo.","");
                s2 = reg.Replace(s2, " ");
                bool found = false;
                if (s2.Length > 0) {
                    foreach (string s3 in comparison) {
                        if (reg.Replace(s3.Replace("[", "").Replace("]", "").Replace("dbo.", ""), " ").Contains(s2)) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        return false;
                    }
                }
            }
            return true;
        }
    }

    public class DataRefKeyedColl : KeyedCollection<string, DataRef> {
        protected override string GetKeyForItem(DataRef item) {
            return item.Key;
        }
    }

}
